static-delta: Pretend that world unreadable objects are new objects
authorMario Sanchez Prada <mario@endlessm.com>
Thu, 15 Dec 2016 19:40:18 +0000 (19:40 +0000)
committerAtomic Bot <atomic-devel@projectatomic.io>
Fri, 16 Dec 2016 14:52:09 +0000 (14:52 +0000)
This will prevent including in the delta the bits to update files that
are not world readable, so that we don't run into a permissions problem
when applying the deltas from a bare-user repository that has a bare
repository set as its parent.

This is the case for Endless when updating flatpak runtimes, as the
temporary directory created in ~/.local/share/flatpak/system-cache will
be of type bare-user with its parent set to /var/lib/flatpak which is a
bare repository in EOS, as it's shared with the one at /ostree/repo.

https://phabricator.endlessm.com/T14159

Closes: #634
Approved by: cgwalters

src/libostree/ostree-repo-static-delta-compilation.c

index 1611d19ee70d3cfea4f1a425a3b924da60629b18..657e8676e1f3a0d4be968a05b1aa2602f99de662 100644 (file)
@@ -843,6 +843,25 @@ process_one_bsdiff (OstreeRepo                       *repo,
   return ret;
 }
 
+static gboolean
+check_object_world_readable (OstreeRepo   *repo,
+                             const char   *checksum,
+                             gboolean     *out_readable,
+                             GCancellable *cancellable,
+                             GError      **error)
+{
+  g_autoptr(GFileInfo) finfo = NULL;
+  guint32 mode;
+
+  if (!ostree_repo_load_file (repo, checksum, NULL, &finfo, NULL,
+                              cancellable, error))
+    return FALSE;
+
+  mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode");
+  *out_readable = (mode & S_IROTH);
+  return TRUE;
+}
+
 static gboolean 
 generate_delta_lowlatency (OstreeRepo                       *repo,
                            const char                       *from,
@@ -973,6 +992,22 @@ generate_delta_lowlatency (OstreeRepo                       *repo,
       const char *from_checksum = value;
       ContentRollsum *rollsum;
       ContentBsdiff *bsdiff;
+      gboolean from_world_readable = FALSE;
+
+      /* We only want to include in the delta objects that we are sure will
+       * be readable by the client when applying the delta, regardless its
+       * access privileges, so that we don't run into permissions problems
+       * when the client is trying to update a bare-user repository with a
+       * bare repository defined as its parent.
+       */
+      if (!check_object_world_readable (repo, from_checksum, &from_world_readable, cancellable, error))
+        goto out;
+      if (!from_world_readable)
+        {
+          g_hash_table_iter_steal (&hashiter);
+          g_hash_table_add (new_reachable_regfile_content, (char*)from_checksum);
+          continue;
+        }
 
       if (!try_content_rollsum (repo, opts, from_checksum, to_checksum,
                                 &rollsum, cancellable, error))